package com.android.functionmanagement.util;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.util.Log;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

import com.android.functionmanagement.globle.ConstantGloble;
import com.pixart.alg.PXIALGMOTION;
import com.xinmeilai.pixart.heartrate.HeartRateDetection;

public class HeartRateUtils {
	private static final String TAG = "HeartRateUtils";
	private static final int MSG_REFRESH_RESULT = 2012;
	private static final int MSG_DETECT_ERROR = 2013;
	private static final int MSG_DETECT_START = 2014;
	private static final int MSG_DETECT_BUSY = 2015;
	private static final int DETECT_COUNT = 400;
	private static final int DETECT_TIME_INTERVAL = 5 * 1000;
    private static final String HEARTRATE_STATUS_FILE = "/proc/HR_status";

	private Thread mLooperThread;
	private Thread mDetectThread;
	private Context mContext;
	private float MEMS_DATA[] = { 0.0F, 0.0F, 0.0F };
	private int mDetectResult = 0;
	private int mDetectCount = 0;
	private boolean isStopDetect = true;
	private int mDeviceFd = -1;
	private long mLastTimeMillis = 0;
	private long mCurrentTimeMillis = 0;
	private List<Integer> mResults = new ArrayList<Integer>();

	public HeartRateUtils(Context context) {
		mContext = context;
	}

	public static boolean hearRateIsOpened() {
		int status = 0;
		try {
			File heartRateStatusFile = new File(HEARTRATE_STATUS_FILE);
			FileReader filereader = new FileReader(heartRateStatusFile);
			try {
				Character result = (char)(filereader.read());
				status = Integer.parseInt(result.toString());
				if (status == 1) {
					return true;
				} else {
					return false;
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		return false;
	}

	public void startHeartRateDetection() {
		if (isStopDetect) {
			if (hearRateIsOpened()) {
				handler.sendEmptyMessageDelayed(MSG_DETECT_BUSY, 30*1000);
				//Log.d(TAG, "==1==HeartRate Busy");
			}else {
				//Log.d(TAG, "==2==HeartRate Start");
			    mDetectThread = new StartDetectThread();
			    mDetectThread.start();
			}
		}
	}

	private void stopHeartRateDetection() {
		if (mDeviceFd > 0) {
			HeartRateDetection.ClosePixart(mDeviceFd);
			if (mLooperThread != null) {
				mLooperThread.interrupt();
			}
		}

		if (mDetectThread != null) {
			mDetectThread.interrupt();
		}

		isStopDetect = true;
		mDetectCount = 0;
	}

	class StartDetectThread extends Thread{
		@Override
		public void run() {
			super.run();
			mDeviceFd = HeartRateDetection.OpenPixart();
			handler.sendEmptyMessage(MSG_DETECT_START);
		}
	}

	class LooperThread extends Thread {

		@Override
		public void run() {
			super.run();
			while (true) {
				if (mDeviceFd > 0) {
					char[] data = HeartRateDetection.GetPpgData(mDeviceFd);
					if ((data != null) && (data.length == 13)) {
						mDetectResult = PXIALGMOTION.Process(data, MEMS_DATA);
						handler.sendEmptyMessage(MSG_REFRESH_RESULT);
						mCurrentTimeMillis = mLastTimeMillis = SystemClock.elapsedRealtime();
						mDetectCount++;
					} else {
						mCurrentTimeMillis = SystemClock.elapsedRealtime();
						if (mCurrentTimeMillis - mLastTimeMillis > DETECT_TIME_INTERVAL) {
							handler.sendEmptyMessage(MSG_DETECT_ERROR);
							break;
						}
					}
				}
				if (isStopDetect || (mDeviceFd < 0)) {
					break;
				}
			}
		}
	}

	private Handler handler = new Handler() {

		@Override
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case MSG_REFRESH_RESULT:
				if ((mDetectResult > 0) && (mDetectCount >= DETECT_COUNT)) {
					mResults.add(mDetectResult);
					if (mResults.size() >= 100) {
						stopHeartRateDetection();
						int count = 0;
						for (int result : mResults) {
							count += result;
						}
						int resultValue = count / mResults.size();
						SharedPreferencesUtils.setParam(mContext, ConstantGloble.HEARTRATE_DATA, ""+resultValue);
						Log.e(TAG, " resultValue = " + resultValue);
						GatherDataUtil.sendGatherData(mContext);
						DeviceUtils.uploadData(mContext, ConstantGloble.UPLOAD_TYPE_OF_HR, 0);
					}
				}
				break;
			case MSG_DETECT_ERROR:
				stopHeartRateDetection();
				SharedPreferencesUtils.setParam(mContext, ConstantGloble.HEARTRATE_DATA, "-1");
				Log.e(TAG, " MSG_DETECT_ERROR ");
				break;
			case MSG_DETECT_START:
				if (mDeviceFd > 0) {
					isStopDetect = false;
					mCurrentTimeMillis = mLastTimeMillis = SystemClock.elapsedRealtime();
					mLooperThread = new LooperThread();
					mLooperThread.start();
				} else {
					SharedPreferencesUtils.setParam(mContext, ConstantGloble.HEARTRATE_DATA, "-1");
					Log.e(TAG, " startHeartRateDetection fd < 0 ");
				}
				break;
			case MSG_DETECT_BUSY:
				startHeartRateDetection();
				break;
			default:
				break;
			}
		}
	};
}
